from fastapi import APIRouter, HTTPException, Depends, Query
from typing import Optional

from database.database_function import get_db
from api.utils import search_similar_vectors
from database.database import RecallHistory
from api.schemas.search import SearchRequest, SearchResponse, RecallHistoryListResponse


router = APIRouter()


@router.post("/search", response_model=SearchResponse, summary="向量检索")
async def search_vectors(request: SearchRequest, db= Depends(get_db)):
    try:
        results = search_similar_vectors(
            query_text=request.query_text,
            doc_id=request.doc_id,
            kb_id=request.kb_id,
            top_k=request.top_k,
            db=db
        )
        return SearchResponse(
            success=True,
            query_text=request.query_text,
            doc_id=request.doc_id,
            kb_id=request.kb_id,
            results=results,
            total_results=len(results)
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"搜索失败: {str(e)}")


@router.get("/knowledge-bases/{kb_id}/recall", response_model=SearchResponse, summary="知识库相似度召回")
async def recall_by_kb(
    kb_id: int,
    q: str = Query(..., description="查询文本"),
    top_k: int = Query(8, ge=1, le=100, description="返回数量"),
    doc_id: Optional[int] = Query(None, description="可选：限定文档ID"),
    db=Depends(get_db)
):
    try:
        results = search_similar_vectors(
            query_text=q,
            doc_id=doc_id,
            kb_id=kb_id,
            top_k=top_k,
            db=db
        )

        history_hits = [
            {
                "doc_id": r.get("doc_id"),
                "doc_name": r.get("doc_name"),
                "chunk_index": r.get("chunk_index"),
                "chunk_text": r.get("chunk_text"),
                "score": r.get("similarity") or r.get("score") or 0
            } for r in results
        ]
        rh = RecallHistory(kb_id=kb_id, query_text=q, hits=history_hits)
        db.add(rh)
        db.commit()

        return SearchResponse(
            success=True,
            query_text=q,
            doc_id=doc_id,
            kb_id=kb_id,
            results=results,
            total_results=len(results)
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"召回失败: {str(e)}")


@router.get("/knowledge-bases/{kb_id}/recall/history", response_model=RecallHistoryListResponse, summary="获取知识库召回历史")
async def list_recall_history(
    kb_id: int,
    limit: int = Query(20, ge=1, le=100),
    db=Depends(get_db)
):
    items = db.query(RecallHistory).filter(RecallHistory.kb_id == kb_id).order_by(RecallHistory.id.desc()).limit(limit).all()
    parsed = [
        {
            "id": it.id,
            "kb_id": it.kb_id,
            "query_text": it.query_text,
            "hits": it.hits or [],
            "created_at": it.created_at,
        } for it in items
    ]
    return RecallHistoryListResponse(success=True, items=parsed)


@router.delete("/knowledge-bases/{kb_id}/recall/history/{history_id}", response_model=dict, summary="删除指定召回历史")
async def delete_recall_history(kb_id: int, history_id: int, db=Depends(get_db)):
    item = db.query(RecallHistory).filter(RecallHistory.id == history_id, RecallHistory.kb_id == kb_id).first()
    if not item:
        raise HTTPException(status_code=404, detail="历史记录不存在")
    db.delete(item)
    db.commit()
    return {"success": True, "message": "已删除"}


